package com.dindang.maintenance.mvp.presenter;

import android.app.Application;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewTreeObserver;

import com.dindang.maintenance.R;
import com.dindang.maintenance.app.utils.TimeComparisonUtils;
import com.dindang.maintenance.mvp.contract.SendOrderContract;
import com.dindang.maintenance.mvp.model.entity.BaseResponse;
import com.dindang.maintenance.mvp.model.entity.Maintain;
import com.dindang.maintenance.mvp.model.entity.Repair;
import com.dindang.maintenance.mvp.ui.adapter.custom.MaintainExecutiveViewAdapter;
import com.dindang.maintenance.mvp.ui.widget.SelectDateDialog;
import com.flyco.tablayout.listener.OnTabSelectListener;
import com.jess.arms.di.scope.ActivityScope;
import com.jess.arms.http.imageloader.ImageLoader;
import com.jess.arms.integration.AppManager;
import com.jess.arms.mvp.BasePresenter;
import com.jess.arms.utils.ArmsUtils;
import com.jess.arms.utils.LogUtils;
import com.jess.arms.utils.RxLifecycleUtils;
import com.longxi.gamer_base.BaseAppConst;
import com.longxi.gamer_base.MyApplication;
import com.longxi.gamer_base.dialog.WaitDialog;
import com.longxi.gamer_base.model.MaintainDetailsEvent;

import org.greenrobot.eventbus.EventBus;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import me.jessyan.rxerrorhandler.core.RxErrorHandler;
import me.jessyan.rxerrorhandler.handler.ErrorHandleSubscriber;
import me.jessyan.rxerrorhandler.handler.RetryWithDelay;


@ActivityScope
public class SendOrderPresenter extends BasePresenter<SendOrderContract.Model, SendOrderContract.View> {
    @Inject
    RxErrorHandler mErrorHandler;
    @Inject
    Application mApplication;
    @Inject
    ImageLoader mImageLoader;
    @Inject
    AppManager mAppManager;

    private String[] mHandling = {"自修", "外派"};
    private int HANDLING_SELF_REPAIR = 0;// 自修
    private int HANDLING_EXPATRIATE = 1;// 外派

    private int executiveWidth = 0;
    private LinearLayoutManager mLayoutManager;
    private MaintainExecutiveViewAdapter mAdapter;
    private List<Repair.MaintenancePeople> mMaintenancePeople = new ArrayList<>();

    private Calendar mCalendar = TimeComparisonUtils.getStartTimeInteger2();// 获取启始时间
    private Maintain.SendParam mSendParam = new Maintain.SendParam();// 选中的日期 默认选中当前时间
    private List<Maintain.SelectDate> mSelectDate = new ArrayList<>();// 可以选择的日期
    private List<Maintain.SelectDate> mSelectStartTime = new ArrayList<>();// 可以选择的开始时间
    private List<Maintain.SelectDate> mSelectEndTime = new ArrayList<>();// 可以选择的结束时间

    private WaitDialog mWaitDialog;
    private Repair.FindRepairsByCorpParam mFindRepairsByCorpParam = new Repair.FindRepairsByCorpParam();
    private Repair.AddFlowParam mAddFlowParam;
    private MaintainDetailsEvent mMaintainDetailsEvent = new MaintainDetailsEvent();

    @Inject
    public SendOrderPresenter(SendOrderContract.Model model, SendOrderContract.View rootView) {
        super(model, rootView);
    }

    public void init() {
        mWaitDialog = new WaitDialog(mRootView.getActivity());
        mAddFlowParam = new Repair.AddFlowParam(mRootView.getActivity().getIntent().getStringExtra("id"),
                BaseAppConst.accountInfo.getCorpId(),
                BaseAppConst.accountInfo.getCorpName(),
                BaseAppConst.accountInfo.getCorpId(),
                "1",
                "1");
        mRootView.getTlHandling().setTabData(mHandling);
        initSelectDate();
        initAdapter();
        initListener();
        getData();
    }

    /**
     * 初始化时间选择数据
     */
    private void initSelectDate() {
        mSendParam = TimeComparisonUtils.getSendParam();
//        mSendParam.selectDate = mCalendar.getTime();
//        mSendParam.startTime = TimeComparisonUtils.hourAdd(mSendParam.selectDate, 1);
//        mSendParam.endTime = calendarAddHour(mSendParam.startTime, 2);

        mRootView.getTvDate().setText(TimeComparisonUtils.dateTChineseString(mSendParam.selectDate));
        mRootView.getTvStartTime().setText(TimeComparisonUtils.dateTTime(mSendParam.startTime));
        mRootView.getTvEndTime().setText(TimeComparisonUtils.dateTTime(mSendParam.endTime));

        mSelectDate.add(new Maintain.SelectDate(mCalendar.getTime(), TimeComparisonUtils.dateTChineseString(mCalendar.getTime()), true));
        for (int i = 1; i < 7; i++) {
            mCalendar.add(Calendar.DATE, +1);
            mCalendar.set(Calendar.HOUR_OF_DAY, 0);
            mCalendar.set(Calendar.MINUTE, 0);
            mCalendar.set(Calendar.SECOND, 0);
            mCalendar.set(Calendar.MILLISECOND, 0);
            mSelectDate.add(new Maintain.SelectDate(mCalendar.getTime(), TimeComparisonUtils.dateTChineseString(mCalendar.getTime()), false));
        }

        initSelectStartTime(mSelectDate.get(mPosition).date, mSendParam.endTime);
        initSelectEndTime(mSendParam.startTime, mSelectDate.get(mPosition + 1).date);
    }

    private int mPosition = 0;
    Calendar mTestCalendar = Calendar.getInstance();

    /**
     * 初始化开始时间选择
     * @param startDate
     * @param endDate
     */
    private void initSelectStartTime(Date startDate, Date endDate){
        mSelectStartTime.clear();
        long halfHour = TimeComparisonUtils.getDatePoor(startDate, endDate);
        for (int i = 0; i <= halfHour - 1; i++) {
            mTestCalendar.setTime(mSelectDate.get(mPosition).date);
            mTestCalendar.add(Calendar.MINUTE, i * 30);
            if(TimeComparisonUtils.isHoursAndMinutesEqual(mSendParam.startTime, mTestCalendar.getTime())){
                mRootView.getTvStartTime().setText(TimeComparisonUtils.dateTTime(mTestCalendar.getTime()));
                mSelectStartTime.add(new Maintain.SelectDate(mTestCalendar.getTime(), TimeComparisonUtils.dateTTime(mTestCalendar.getTime()), true));
            }else{
                mSelectStartTime.add(new Maintain.SelectDate(mTestCalendar.getTime(), TimeComparisonUtils.dateTTime(mTestCalendar.getTime()), false));
            }
        }
    }

    /**
     * 初始化结束时间选择
     * @param startDate
     * @param endDate
     */
    private void initSelectEndTime(Date startDate, Date endDate){
        mSelectEndTime.clear();
        long halfHour = TimeComparisonUtils.getDatePoor(startDate, endDate);
        for (int i = 1; i <= halfHour - 1; i++) {
            mTestCalendar.setTime(startDate);
            mTestCalendar.add(Calendar.MINUTE, i * 30);
            if(TimeComparisonUtils.isHoursAndMinutesEqual(mSendParam.endTime, mTestCalendar.getTime())){
                mRootView.getTvEndTime().setText(TimeComparisonUtils.dateTTime(mTestCalendar.getTime()));
                mSelectEndTime.add(new Maintain.SelectDate(mTestCalendar.getTime(), TimeComparisonUtils.dateTTime(mTestCalendar.getTime()), true));
            }else{
                mSelectEndTime.add(new Maintain.SelectDate(mTestCalendar.getTime(), TimeComparisonUtils.dateTTime(mTestCalendar.getTime()), false));
            }
        }
    }

    /**
     * 适配器初始化
     */
    private void initAdapter() {
        mLayoutManager=new LinearLayoutManager(mRootView.getActivity());
        mLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);//横排
        mRootView.getRvExecutive().setLayoutManager(mLayoutManager);
        mAdapter = new MaintainExecutiveViewAdapter(mMaintenancePeople);
        mRootView.getRvExecutive().setAdapter(mAdapter);
        ViewTreeObserver vto = mRootView.getRvExecutive().getViewTreeObserver();
        vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            public boolean onPreDraw() {
                if(executiveWidth == 0){
                    executiveWidth = mRootView.getRvExecutive().getMeasuredWidth();
                    mAdapter.setExecutiveWidth(executiveWidth);
                }
                return true;
            }
        });
    }

    private int mExecutivePosition = 0;//当前位置
    private int mScrollFew = 4;//点击滚动按钮 向右滚动几条
    /**
     * 点击事件初始化
     */
    private void initListener() {
        mRootView.getTvDate().setOnClickListener(v -> dialogSelectDate());
        mRootView.getTvStartTime().setOnClickListener(v -> dialogSelectStartTime());
        mRootView.getTvEndTime().setOnClickListener(v -> dialogSelectEndTime());
        mRootView.getRvExecutive().addOnScrollListener(new RecyclerView.OnScrollListener() {
            @Override
            public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                super.onScrolled(recyclerView, dx, dy);
                int firstVisibleItemPosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
                if(firstVisibleItemPosition == 0){
                    mExecutivePosition = firstVisibleItemPosition - 1 + mScrollFew;
                }else{
                    mExecutivePosition = firstVisibleItemPosition + mScrollFew;
                }
                LogUtils.debugInfo("onScrolled position", firstVisibleItemPosition + "");
            }
        });
        mRootView.getIvToRight().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mExecutivePosition != -1) {
                    mExecutivePosition += mScrollFew;
                    mRootView.getRvExecutive().smoothScrollToPosition(mExecutivePosition >= mMaintenancePeople.size() ? mMaintenancePeople.size() : mExecutivePosition);
                }
            }
        });
        mRootView.getTlHandling().setOnTabSelectListener(new OnTabSelectListener() {
            @Override
            public void onTabSelect(int position) {
                if(position == HANDLING_SELF_REPAIR){
                    mRootView.getGroupAssignedUnit().setVisibility(View.GONE);
                    showMaintenancePeople();
                    mAddFlowParam.cType = "1";
                }else{
                    mRootView.getGroupAssignedUnit().setVisibility(View.VISIBLE);
                    mRootView.getIvToRight().setVisibility(View.GONE);
                    mRootView.getTvExecutive().setVisibility(View.GONE);
                    mRootView.getRvExecutive().setVisibility(View.GONE);
                    mAddFlowParam.cType = "3";
                }
            }

            @Override
            public void onTabReselect(int position) {

            }
        });

        mAdapter.setListener(new MaintainExecutiveViewAdapter.OnClickListener() {
            @Override
            public void onClick(int position) {
                mMaintenancePeople.get(position).setSelect(!mMaintenancePeople.get(position).isSelect());;
                mAdapter.notifyItemChanged(position);
            }
        });

        mRootView.getTvCommit().setOnClickListener(v -> {
            mAddFlowParam.cRemark = mRootView.getEtExplainValue().getText().toString().trim();
            mAddFlowParam.dAppointDate = TimeComparisonUtils.dateTDateString(mSendParam.selectDate);
            mAddFlowParam.cStartDate = TimeComparisonUtils.dateTTimeString(mSendParam.startTime);
            mAddFlowParam.cEndDate = TimeComparisonUtils.dateTTimeString(mSendParam.endTime);
            if("1".equals(mAddFlowParam.cType)){
                StringBuffer executorId = new StringBuffer();
                StringBuffer executor = new StringBuffer();
                for (Repair.MaintenancePeople maintenancePeople : mMaintenancePeople) {
                    if(maintenancePeople.isSelect()){
                        executorId.append(maintenancePeople.c_id);
                        executorId.append(",");
                        executor.append(maintenancePeople.c_username);
                        executor.append(",");
                    }
                }
                if(executorId.length() > 0){
                    mAddFlowParam.executorId = executorId.substring(0, executorId.length() - 1);
                    mAddFlowParam.executor = executor.substring(0, executor.length() - 1);
                }else{
                    ArmsUtils.makeText(mApplication, ArmsUtils.getString(mApplication, R.string.maintenance_please_select_executive));
                }

            }else if("3".equals(mAddFlowParam.cType)){
                if("".equals(mAddFlowParam.executor)){
                    ArmsUtils.makeText(mApplication, mRootView.getEtAssignedUnitValue().getHint().toString());
                    return;
                }
                mAddFlowParam.executorId = "";
                mAddFlowParam.executor = mRootView.getEtAssignedUnitValue().getText().toString().trim();
            }

            if("".equals(mAddFlowParam.cRemark)){
                ArmsUtils.makeText(mApplication, ArmsUtils.getString(mApplication, R.string.maintenance_please_enter_delivery_instructions));
                return;
            }

            insertFlow();
        });
    }

    /**
     * 添加新流程信息
     */
    private void insertFlow() {
        mWaitDialog.showWaitingDialog(ArmsUtils.getString(mApplication, R.string.data_post));
        mModel.insertFlow(mAddFlowParam)
        .subscribeOn(Schedulers.io())
        .retryWhen(new RetryWithDelay(2, 2))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
        .doOnSubscribe(disposable -> {

        }).subscribeOn(AndroidSchedulers.mainThread())
        .observeOn(AndroidSchedulers.mainThread())
        .doFinally(() -> {
            mWaitDialog.hideWaitingDialog();
        })
        .compose(RxLifecycleUtils.bindToLifecycle(mRootView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
        .subscribe(new ErrorHandleSubscriber<BaseResponse>(mErrorHandler) {
            @Override
            public void onNext(BaseResponse response) {
                if(response.getStatus().equals(BaseAppConst.OUT_TOKEN)){
                    MyApplication.getInstance().gotoLoginActivity();
                }
                ArmsUtils.makeText(mApplication, response.getStatuMsg());
                if(!response.isSuccess()){
                    return;
                }

                EventBus.getDefault().post(mMaintainDetailsEvent);
                mAppManager.getCurrentActivity().finish();
            }
        });
    }

    private void getData() {
        findRepairsByCorp();
    }

    /**
     * 查询当前公司所有维修工
     */
    private void findRepairsByCorp(){
        mFindRepairsByCorpParam.setFindRepairsByCorp(mRootView.getActivity().getIntent().getStringExtra("id"), BaseAppConst.accountInfo.getCorpId());
        mModel.findRepairsByCorp(mFindRepairsByCorpParam)
        .subscribeOn(Schedulers.io())
        .retryWhen(new RetryWithDelay(2, 2))//遇到错误时重试,第一个参数为重试几次,第二个参数为重试的间隔
        .doOnSubscribe(disposable -> {

        }).subscribeOn(AndroidSchedulers.mainThread())
        .observeOn(AndroidSchedulers.mainThread())
        .doFinally(() -> {

        })
        .compose(RxLifecycleUtils.bindToLifecycle(mRootView))//使用 Rxlifecycle,使 Disposable 和 Activity 一起销毁
        .subscribe(new ErrorHandleSubscriber<BaseResponse<List<Repair.MaintenancePeople>>>(mErrorHandler) {
            @Override
            public void onError(Throwable t) {
                super.onError(t);
                ArmsUtils.snackbarText(t.getMessage());
            }

            @Override
            public void onNext(BaseResponse<List<Repair.MaintenancePeople>> response) {
                if(response.getStatus().equals(BaseAppConst.OUT_TOKEN)){
                    MyApplication.getInstance().gotoLoginActivity();
                }
                if(!response.isSuccess()){
                    ArmsUtils.makeText(mApplication, response.getStatuMsg());
                    return;
                }

                mMaintenancePeople.addAll(response.getData());
                mAdapter.notifyDataSetChanged();

                showMaintenancePeople();
            }
        });

    }

    /**
     * 显示自修人员
     */
    private void showMaintenancePeople(){
        mRootView.getTvExecutive().setVisibility(View.VISIBLE);
        mRootView.getRvExecutive().setVisibility(View.VISIBLE);
        if(mMaintenancePeople.size() == 0){
            mRootView.getIvToRight().setVisibility(View.GONE);
        }else if(mMaintenancePeople.size() > 0 && mMaintenancePeople.size() <= 4){
            mRootView.getIvToRight().setVisibility(View.GONE);
        }else{
            mRootView.getIvToRight().setVisibility(View.VISIBLE);
        }
    }

    private SelectDateDialog.Builder mSelectDateDialog;
    /**
     * 日期弹出框
     */
    private void dialogSelectDate() {
        if(mSelectDateDialog != null){
            mSelectDateDialog.show();
        }else{
            mSelectDateDialog = new SelectDateDialog.Builder(mRootView.getActivity());
            mSelectDateDialog
            .setTitle("请选择执行日期")
            .setListener(new SelectDateDialog.OnClickListener() {
                @Override
                public void onClick(int position) {
                    mPosition = position;
                    mSendParam.selectDate = mSelectDate.get(position).date;
                    mRootView.getTvDate().setText(mSelectDate.get(position).dateString);

                    calendarAddDate(mSendParam.selectDate, 1);
                    long halfHour = TimeComparisonUtils.getDatePoor(mSendParam.selectDate, mTestCalendar.getTime());
                    for (int i = 0; i <= halfHour - 1; i++) {
                        mTestCalendar.setTime(mSelectDate.get(mPosition).date);
                        mTestCalendar.add(Calendar.MINUTE, i * 30);
                        if(TimeComparisonUtils.isHoursAndMinutesEqual(mSendParam.startTime, mTestCalendar.getTime())){
                            mSendParam.startTime = mTestCalendar.getTime();
                        }
                    }

                    calendarAddDate(mSendParam.selectDate, 1);
                    if(mSendParam.startTime.getTime() < mSendParam.selectDate.getTime() || mSendParam.startTime.getTime() >= mTestCalendar.getTime().getTime()){
                        if("今天".equals(mSelectDate.get(position).dateString)){
                            mSendParam.startTime = TimeComparisonUtils.hourAdd(mSendParam.selectDate, 1);
                        }else{
                            mSendParam.startTime = mSendParam.selectDate;
                        }
                    }

                    for (int i = 1; i <= halfHour - 1; i++) {
                        mTestCalendar.setTime(mSendParam.selectDate);
                        mTestCalendar.add(Calendar.MINUTE, i * 30);
                        if(TimeComparisonUtils.isHoursAndMinutesEqual(mSendParam.endTime, mTestCalendar.getTime())){
                            mSendParam.endTime = mTestCalendar.getTime();
                        }
                    }

                    calendarAddDate(mSendParam.startTime, 1);
                    if(mSendParam.endTime.getTime() < mSendParam.startTime.getTime() || mSendParam.endTime.getTime() >= mTestCalendar.getTime().getTime()){
                        mSendParam.endTime = TimeComparisonUtils.calendarAddHour(mSendParam.startTime, 2);
                    }

                    initSelectStartTime(mSendParam.selectDate, mSendParam.endTime);
                    calendarAddDate(mSendParam.selectDate, 1);
                    initSelectEndTime(mSendParam.startTime, mTestCalendar.getTime());

                    mSelectDateDialog.dismiss();
                }
            })
            .create()
            .show();
        }
        mSelectDateDialog.setSelectDate(mSelectDate);
    }

    private SelectDateDialog.Builder mSelectStartTimeDialog;
    /**
     * 开始时间弹出框
     */
    private void dialogSelectStartTime() {
        if(mSelectStartTimeDialog != null){
            mSelectStartTimeDialog.show();
        }else{
            mSelectStartTimeDialog = new SelectDateDialog.Builder(mRootView.getActivity());
            mSelectStartTimeDialog
            .setTitle("请选择执行开始时间")
            .setListener(new SelectDateDialog.OnClickListener() {
                @Override
                public void onClick(int position) {
                    mSendParam.startTime = mSelectStartTime.get(position).date;
                    mRootView.getTvStartTime().setText(mSelectStartTime.get(position).dateString);
                    mSelectStartTimeDialog.dismiss();

                    calendarAddDate(mSendParam.startTime, 1);
                    initSelectEndTime(mSendParam.startTime, mTestCalendar.getTime());
                }
            })
            .create()
            .show();
        }
        mSelectStartTimeDialog.setSelectDate(mSelectStartTime);
    }

    private SelectDateDialog.Builder mSelectEndTimeDialog;
    /**
     * 结束时间弹出框
     */
    private void dialogSelectEndTime() {
        if(mSelectEndTimeDialog != null){
            mSelectEndTimeDialog.show();
        }else{
            mSelectEndTimeDialog = new SelectDateDialog.Builder(mRootView.getActivity());
            mSelectEndTimeDialog
            .setTitle("请选择执行结束时间")
            .setListener(new SelectDateDialog.OnClickListener() {
                @Override
                public void onClick(int position) {
                    mSendParam.endTime = mSelectEndTime.get(position).date;
                    mRootView.getTvEndTime().setText(mSelectEndTime.get(position).dateString);
                    mSelectEndTimeDialog.dismiss();

                    initSelectStartTime(mSelectDate.get(mPosition).date, mSendParam.endTime);
                }
            })
            .create()
            .show();
        }
        mSelectEndTimeDialog.setSelectDate(mSelectEndTime);
    }

    /**
     * 获取第二天0时0分时间
     * @param date
     * @param addDateSize
     */
    private void calendarAddDate(Date date, int addDateSize){
        mTestCalendar.setTime(date);
        mTestCalendar.add(Calendar.DATE, addDateSize);
        mTestCalendar.set(Calendar.HOUR_OF_DAY, 0);
        mTestCalendar.set(Calendar.MINUTE, 0);
        mTestCalendar.set(Calendar.SECOND, 0);
        mTestCalendar.set(Calendar.MILLISECOND, 0);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        this.mErrorHandler = null;
        this.mAppManager = null;
        this.mImageLoader = null;
        this.mApplication = null;

        this.mAdapter = null;
        this.mMaintenancePeople = null;
        this.mLayoutManager = null;

        this.mCalendar = null;
        this.mSendParam = null;
        this.mSelectDateDialog = null;
        this.mSelectStartTimeDialog = null;
        this.mSelectStartTime = null;
        this.mSelectStartTime = null;
        this.mSelectEndTime = null;

        this.mTestCalendar = null;
        this.mWaitDialog = null;

        this.mMaintainDetailsEvent = null;
    }
}
